package com.infodms.dms.actions.sales.marketmanage.planissued;

import java.sql.ResultSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.infodms.dms.bean.AclUserBean;
import com.infodms.dms.common.Constant;
import com.infodms.dms.common.ErrorCodeConstant;
import com.infodms.dms.dao.common.BaseDao;
import com.infodms.dms.dao.sales.marketmanage.planmanage.ActivitiesSummaryReportDao;
import com.infodms.dms.exception.BizException;
import com.infodms.dms.po.TcCodePO;
import com.infodms.dms.po.TtCampaignExecutePO;
import com.infodms.dms.po.TtCampaignSpaceExecutePO;
import com.infodms.dms.po.TtVsCostPO;
import com.infodms.dms.util.CommonUtils;
import com.infoservice.mvc.context.ActionContext;
import com.infoservice.mvc.context.RequestWrapper;
import com.infoservice.po3.bean.PO;

/**
 * @Title: CHANADMS
 *
 * @Description
 *
 * @Copyright Copyright (c) 2010
 *
 * @Company  www.infoservice.com.cn
 * @Date 2010-10-1
 *
 * @author fengalon
 * @mail   wanghanxian@infoservice.com.cn
 * @version 1.0
 * @remark 
 */
public class ActivitiesCostOpera extends BaseDao {
	public Logger logger = Logger.getLogger(ActivitiesCostOpera.class);
	ActivitiesSummaryReportDao dao = ActivitiesSummaryReportDao.getInstance();
	ActionContext act = ActionContext.getContext();
	RequestWrapper request = act.getRequest();

	/*--------------------------------------------------   其他类调用方法   --------------------------------------------------*/
	
	public void activeExecOpera(String areaidA, String costType, String flagA, String camType) throws Exception {
		AclUserBean logonUser = (AclUserBean) act.getSession().get(Constant.LOGON_USER);

		try {
			String flag = flagA;							// 获得操作动作,0为审核通过,1为驳回,3表示大区自发
			String areaId = areaidA	;				// 获得业务范围
			String dutyType = logonUser.getDutyType();							// 获取组织层次

			String[] activeCost = request.getParamValues("planCost1");					// 获得活动费用的计划费用
			String[] mediaCost = request.getParamValues("planCost2");					// 获得媒体投放费用的计划费用

			Double cost = new Double(0);									

			// 1、若activeCost和mediaCost同时为null时,则跳出方法
			if (null == activeCost && null == mediaCost) {
				return;
			}

			// 2、若activeCost和mediaCost数组长度小于1是,则跳出方法
			if (null != activeCost && null != mediaCost
					&& activeCost.length < 1 && mediaCost.length < 1) {
				return;
			}

			// 3、根据活动费用的费用来源,分别汇总活动计划费用的总费用
			if (null != activeCost && activeCost.length > 0) {
				// 调用方法，获取活动总费用
				cost = getTotolCost(activeCost, costType) ;
			}

			// 4、根据媒体投放费用的费用来源,分别媒体投放费用的总费用
			if (null != mediaCost && mediaCost.length > 0) {
				// 调用方法，获取媒体投放总费用
				cost += getTotolCost(mediaCost, costType) ;
			}
			
			if (Constant.DUTY_TYPE_DEALER.toString().equals(dutyType)) {
				String dealerIds = logonUser.getDealerId();						// 当前用户的dealerId
				String dealerId = "";											// 初始化经销商id

				List<Map<String, Object>> delList = dao.getDel(dealerIds, areaId);												// 取得当前用户在业务范围为areaId的唯一dealerId

				if (!CommonUtils.isNullList(delList)) {
					dealerId = delList.get(0).get("DEALER_ID").toString();		// 获取经销商id
				} else {
					throw new RuntimeException("经销商未维护,业务范围id为'" + areaId + "'下没有对应经销商！");								// 抛出异常
				}

				if(costType.equals(Constant.COST_TYPE_01.toString())) {
					opera(Long.parseLong(dealerId), areaId, costType, cost, flag);					// 调用经销商操作方法：提报
				}
			}

			if (Constant.DUTY_TYPE_LARGEREGION.toString().equals(dutyType)) {
				Long orgId = logonUser.getOrgId();								// 获得当前登录用户所在区域组织id
				// 表示区域自发提报活动执行方案
				if ("3".equals(flag)) {	// 大区第一次提报
					if(costType.equals(Constant.COST_TYPE_02.toString())) {
						opera(orgId, areaId, costType, cost, flag) ;
					}
					
					return ;
				} else if("1".equals(flag) && camType.equals(Constant.CAMPAIGN_TYPE_03.toString())) {	// 大区驳回
					if(costType.equals(Constant.COST_TYPE_02.toString())) {
						opera(orgId, areaId, costType, cost, flag) ;
					}
					
					return ;
				}
				
				String campaignExecId = request.getParamValue("executeId");		// 获得当前选择的活动执行方案ID

				TtCampaignExecutePO ce = new TtCampaignExecutePO();
				ce.setExecuteId(Long.parseLong(campaignExecId));

				List<TtCampaignExecutePO> ceList = dao.select(ce);
				
				if (!CommonUtils.isNullList(ceList)) {
					String dealerId = ceList.get(0).getDealerId().toString();	// 获得当前选择的活动执行方案的经销商ID
					String checkStatus = ceList.get(0).getCheckStatus().toString();										// 获得当前选择的活动执行方案的审核状态

					// 判断是区域第一次审核（CAMPAIGN_CHECK_STATUS_03为“方案待大区审核”）
					if ((Constant.CAMPAIGN_CHECK_STATUS_03.toString()).equals(checkStatus) && "0".equals(flag)) {
						if(costType.equals(Constant.COST_TYPE_02.toString())) {
							opera(orgId, areaId, costType, cost, flag);	// 调用区域操作方法：审核通过。flag=0
						}
					}

					// 判断是区域第一次驳回（CAMPAIGN_CHECK_STATUS_03为“方案待大区审核”）
					if ((Constant.CAMPAIGN_CHECK_STATUS_03.toString()).equals(checkStatus) && "1".equals(flag)) {
						if(costType.equals(Constant.COST_TYPE_01.toString())) {
							opera(Long.parseLong(dealerId), areaId, costType, cost, flag);			// 调用经销商操作方法：驳回。flag=1
						}
					}

					// 判断不是区域第一次驳回（CAMPAIGN_CHECK_STATUS_03为“方案待大区审核”）
					if (!(Constant.CAMPAIGN_CHECK_STATUS_03.toString()).equals(checkStatus) && "1".equals(flag)) {
						if(costType.equals(Constant.COST_TYPE_02.toString())) {
							opera(orgId, areaId, costType, cost, flag);	// 调用区域操作方法：驳回。flag=1
						}
						
						if(costType.equals(Constant.COST_TYPE_01.toString())) {
							opera(Long.parseLong(dealerId), areaId, costType, cost, flag);			// 调用经销商操作方法：驳回。flag=1
						}
					}
				}
			}

			if (Constant.DUTY_TYPE_COMPANY.toString().equals(dutyType)) {
				Long parkId = logonUser.getOrgId();								// 获得当前登录用户所在车场组织id
				String campaignExecId = request.getParamValue("executeId");		// 获得当前选择的活动执行方案ID

				if (camType.equals(Constant.CAMPAIGN_TYPE_03.toString())) {		// 如果活动为区域自发，则执行以下语句
					TtCampaignSpaceExecutePO ce = new TtCampaignSpaceExecutePO() ;
					ce.setSpaceId(Long.parseLong(campaignExecId)) ;
					
					List<TtCampaignSpaceExecutePO> ceList = dao.select(ce);
					
					if (!CommonUtils.isNullList(ceList)) {
						String areaOrgId = ceList.get(0).getOrgId().toString();
						String checkStatus = ceList.get(0).getCheckStatus().toString();			// 获得当前选择的活动执行方案的审核状态
						
						// 判断是总部第一次审核通过或驳回（CAMPAIGN_CHECK_STATUS_15为“方案待市场专员审核”；CAMPAIGN_CHECK_STATUS_17为“方案待大客户专员审核”）
						if ((Constant.CAMPAIGN_CHECK_STATUS_15.toString()).equals(checkStatus) || (Constant.CAMPAIGN_CHECK_STATUS_17.toString()).equals(checkStatus)) {
							if ("0".equals(flag) && !costType.equals(Constant.COST_TYPE_02.toString())) {	// 审核通过并且费用类型不是区域费用
								opera(parkId, areaId, costType, cost, flag);	// 调用总部操作方法：通过。flag=0
							}
							
							if ("1".equals(flag) && costType.equals(Constant.COST_TYPE_02.toString())) {	// 审核驳回并且费用类型为区域费用
								opera(Long.parseLong(areaOrgId), areaId, costType, cost, flag);	// 调用区域操作方法：驳回。flag=1
							}
							
							return ;
						}

						// 判断不是总部第一次驳回（CAMPAIGN_CHECK_STATUS_15为“方案待市场专员审核”；CAMPAIGN_CHECK_STATUS_17为“方案待大客户专员审核”）
						if (!(Constant.CAMPAIGN_CHECK_STATUS_15.toString()).equals(checkStatus) || !(Constant.CAMPAIGN_CHECK_STATUS_17.toString()).equals(checkStatus)) {
							if ("1".equals(flag)) {
								if(costType.equals(Constant.COST_TYPE_02.toString())) {
									opera(Long.parseLong(areaOrgId), areaId, costType, cost, flag);	// 调用区域操作方法：驳回。flag=1
								}
								
								if(!costType.equals(Constant.COST_TYPE_02.toString())) {
									opera(parkId, areaId, costType, cost, flag);	// 调用总部操作方法：驳回。flag=1
								}
							}
							
							return ;
						}
					}
				} else {
					TtCampaignExecutePO ce = new TtCampaignExecutePO();
					ce.setExecuteId(Long.parseLong(campaignExecId));
	
					List<TtCampaignExecutePO> ceList = dao.select(ce);
					
					if (!CommonUtils.isNullList(ceList)) {
						String dealerId = ceList.get(0).getDealerId().toString();	// 获得当前选择的活动执行方案的经销商ID
						String checkStatus = ceList.get(0).getCheckStatus().toString();										// 获得当前选择的活动执行方案的审核状态
						Long orgId = new Long(0);									// 初始化区域id

						List<Map<String, Object>> orgList = dao.getOrgId(dealerId);	// 调用方法：通过经销商ID查找其属于的区域ID

						if (!CommonUtils.isNullList(orgList)) {
							orgId = Long.parseLong(orgList.get(0).get("ORG_ID").toString());									// 获取区域id
						} else {
							throw new RuntimeException("经销商未维护,请将经销商id为'" + dealerId + "'的经销商维护到区域下！");			// 抛出异常
						}

						// 判断是总部第一次审核或驳回（CAMPAIGN_CHECK_STATUS_15为“方案待市场专员审核”；CAMPAIGN_CHECK_STATUS_17为“方案待大客户专员审核”）
						if ((Constant.CAMPAIGN_CHECK_STATUS_15.toString()).equals(checkStatus) || (Constant.CAMPAIGN_CHECK_STATUS_17.toString()).equals(checkStatus)) {
							if ("0".equals(flag)) {
								if(costType.equals(Constant.COST_TYPE_03.toString()) || costType.equals(Constant.COST_TYPE_04.toString())) {
									opera(parkId, areaId, costType, cost, flag);	// 调用总部操作方法：审核通过。flag=0
								}
							} else {
								if(costType.equals(Constant.COST_TYPE_01.toString())) {
									opera(Long.parseLong(dealerId), areaId, costType, cost, flag);			// 调用经销商操作方法：驳回。flag=1
								}
								
								if(costType.equals(Constant.COST_TYPE_02.toString())) {
									opera(orgId, areaId, costType, cost, flag);	// 调用区域操作方法：驳回。flag=1
								}
							}
							
							return ;
						}

						// 判断不是总部第一次驳回（CAMPAIGN_CHECK_STATUS_15为“方案待市场专员审核”；CAMPAIGN_CHECK_STATUS_17为“方案待大客户专员审核”）
						if (!(Constant.CAMPAIGN_CHECK_STATUS_15.toString()).equals(checkStatus) || !(Constant.CAMPAIGN_CHECK_STATUS_17.toString()).equals(checkStatus)) {
							if ("1".equals(flag)) {
								if(costType.equals(Constant.COST_TYPE_01.toString())) {
									opera(Long.parseLong(dealerId), areaId, costType, cost, flag);			// 调用经销商操作方法：驳回。flag=1
								} else if(costType.equals(Constant.COST_TYPE_02.toString())) {
									opera(orgId, areaId, costType, cost, flag);		// 调用区域操作方法：驳回。flag=1
								} else {
									opera(parkId, areaId, costType, cost, flag);	// 调用总部操作方法：驳回。flag=1
								}
							}
							
							return ;
						}
					}
				}
			}
		} catch(RuntimeException e) {
			BizException e1 = new BizException(act,e,ErrorCodeConstant.PUTIN_FAILURE_CODE,e.getMessage());
			logger.error(logonUser,e1);
			act.setException(e);
		}
		catch (Exception e) {													// 异常方法
			BizException e1 = new BizException(act, e,
					ErrorCodeConstant.SPECIAL_MEG, "活动费用操作错误");
			logger.error(logonUser, e1);
			act.setException(e1);
		}
	}
	
	/**
	 * 对市场活动总结的帐户资金进行操作，包括：活动总结的审核通过。
	 * @param void
	 * @return void
	 * @throws Exception
	 */
	public void activeSummaryOpera(String areaIdA, String costType, String camType) throws Exception {
		AclUserBean logonUser = (AclUserBean) act.getSession().get(Constant.LOGON_USER);

		try {
			String areaId = areaIdA;							// 获得业务范围
			String dutyType = logonUser.getDutyType();							// 获取组织层次
			String campaignExecId = request.getParamValue("executeId");					// 获得当前选择的活动执行方案ID

			String[] activeCost = request.getParamValues("planCost1");					// 获得活动费用的计划费用
			String[] mediaCost = request.getParamValues("planCost2");					// 获得媒体投放费用的计划费用
			String[] activeNegotiate = request.getParamValues("CAM");				// 获得活动费用的兑现费用
			String[] mediaNegotiate = request.getParamValues("MED");				// 获得媒体投放费用的兑现费用

			Double cost = new Double(0);									
			
			Double negotiateCost = new Double(0);							

			// 1、若activeCost和mediaCost同时为null时,则跳出方法
			if (null == activeCost && null == mediaCost) {
				return;
			}

			// 2、若activeCost和mediaCost数组长度小于1是,则跳出方法
			if (null != activeCost && null != mediaCost && activeCost.length < 1 && mediaCost.length < 1) {
				return;
			}

			// 3、根据活动费用的费用来源,分别汇总活动计划费用的总费用
			if (null != activeCost && activeCost.length > 0) {
				// 调用方法，获取活动总费用
				cost = getTotolCost(activeCost, costType) ;
				
				// 调用方法，获取活动兑现总费用集合
				negotiateCost = getTotolCost(activeNegotiate, costType) ;
			}

			// 4、根据媒体投放费用的费用来源,分别媒体投放费用的总费用
			if (null != mediaCost && mediaCost.length > 0) {
				// 调用方法，获取媒体投放总费用集合
				cost += getTotolCost(mediaCost, costType) ;
				
				// 调用方法，获取媒体投放兑现总费用集合
				negotiateCost += getTotolCost(mediaNegotiate, costType) ;
			}
			
			if((Constant.DUTY_TYPE_COMPANY.toString()).equals(dutyType)) {
				Long parkId = logonUser.getOrgId();								// 获得当前登录用户所在车场组织id

				if (camType.equals(Constant.CAMPAIGN_TYPE_03.toString())) {		// 如果活动为区域自发，则执行以下语句
					TtCampaignSpaceExecutePO ce = new TtCampaignSpaceExecutePO() ;
					ce.setSpaceId(Long.parseLong(campaignExecId)) ;
					
					List<TtCampaignSpaceExecutePO> ceList = dao.select(ce);
					
					if (!CommonUtils.isNullList(ceList)) {
						String areaOrgId = ceList.get(0).getOrgId().toString();
						
						if(costType.equals(Constant.COST_TYPE_02.toString())) {
							opera(Long.parseLong(areaOrgId), areaId, costType, cost, negotiateCost) ;
						}
						
						if(!costType.equals(Constant.COST_TYPE_02.toString())) {
							opera(parkId, areaId, costType, cost, negotiateCost) ;
						}
					}
				} else {
					TtCampaignExecutePO ce = new TtCampaignExecutePO();
					ce.setExecuteId(Long.parseLong(campaignExecId));
	
					List<TtCampaignExecutePO> ceList = dao.select(ce);
	
					if (!CommonUtils.isNullList(ceList)) {
						String dealerId = ceList.get(0).getDealerId().toString();	// 获得当前选择的活动执行方案的经销商ID
						Long orgId = new Long(0);									// 初始化区域id
	
						List<Map<String, Object>> orgList = dao.getOrgId(dealerId);	// 调用方法：通过经销商ID查找其属于的区域ID
	
						if (!CommonUtils.isNullList(orgList)) {
							orgId = Long.parseLong(orgList.get(0).get("ORG_ID").toString());									// 获取区域id
						} else {
							throw new RuntimeException("经销商未维护,请将经销商id为'" + dealerId + "'的经销商维护到区域下！");			// 抛出异常
						}
						
						if(costType.equals(Constant.COST_TYPE_01.toString())) {
							opera(Long.parseLong(dealerId), areaId, costType, cost, negotiateCost) ;
						} else if(costType.equals(Constant.COST_TYPE_02.toString())) {
							opera(orgId, areaId, costType, cost, negotiateCost) ;
						} else {
							opera(parkId, areaId, costType, cost, negotiateCost) ;
						}
					}
				}
			}
		}catch(RuntimeException e) {
			BizException e1 = new BizException(act,e,ErrorCodeConstant.PUTIN_FAILURE_CODE,e.getMessage());
			logger.error(logonUser,e1);
			act.setException(e);
		} 
		catch (Exception e) {													// 异常方法
			BizException e1 = new BizException(act, e,
					ErrorCodeConstant.SPECIAL_MEG, "活动费用操作错误");
			logger.error(logonUser, e1);
			act.setException(e1);
		}
	}
	
	/*--------------------------------------------------   本类中的通用方法   --------------------------------------------------*/
	
	/**
	 * 获得活动执行方案各个费用来源及费用类型的总金额
	 * @param cost 活动执行方案费用
	 * @param source 活动执行方案费用来源
	 * @param type 活动执行方案费用类型
	 * @return Map
	 */
	private Double getTotolCost(String[] cost, String type) {
		int len = cost.length;												// 获得传回活动费用信息条数
		
		Double totalCost = new Double("0") ;

		for (int i = 0; i < len; i++) {
			StringBuffer speCost = new StringBuffer("") ;
			String[] specialCost = cost[i].split(",") ;
			int costLen = specialCost.length ;
			
			for(int j=0; j<costLen; j++) {
				speCost.append(specialCost[j]) ;
			}
			
			totalCost += Double.parseDouble(speCost.toString()) ;
		}
		
		return totalCost ;
	}
	
	// 活动执行方案操作
	private void opera(Long id, String areaId, String type, Double cost, String flag) {
		TtVsCostPO tvc = new TtVsCostPO();
		tvc.setAreaId(Long.parseLong(areaId)) ;
		tvc.setCostType(Integer.parseInt(type)) ;
		
		if (Constant.COST_TYPE_01.toString().equals(type)) {
			tvc.setDealerId(id) ;
		} else {
			tvc.setOrgId(id);
		}
		
		TtVsCostPO tvcA = new TtVsCostPO();

		costUpdate(cost, getCodeName(type), tvc, tvcA, flag) ;
	}
	
	/**
	 * 重载costUpdate()方法
	 * 活动执行方案操作，对活动执行方案对应帐户的冻结资金和可用余额进行操作。
	 */
	private void costUpdate(Double cost, String typeName, TtVsCostPO tvc, TtVsCostPO tvcA, String flag) {
		Double freezeAmount = new Double(0);									// 冻结资金
		Double availableAmount = new Double(0);									// 可用余额
		
		if (cost > 0) {
			List<TtVsCostPO> costList = dao.select(tvc);						

			if (!CommonUtils.isNullList(costList)) {
				if ("0".equals(flag) || "3".equals(flag)) {											// 审核通过或大区提报
					freezeAmount = costList.get(0).getFreezeAmount() + cost ;				// 修改后的冻结资金
					availableAmount = costList.get(0).getAvailableAmount() - cost ;		// 修改后的可用余额
					
					/*// 检验广告可用余额是否小于0.若小于0,则抛出异常
					if(availableAmount < 0) {
						throw new RuntimeException(typeName + "可用余额不足！") ;
					}*/
				} else {														// 驳回
					freezeAmount = costList.get(0).getFreezeAmount() - cost;				// 红冲冻结资金
					availableAmount = costList.get(0).getAvailableAmount() + cost;		// 红冲可用余额
				}

				tvcA.setFreezeAmount(freezeAmount);
				tvcA.setAvailableAmount(availableAmount);

				dao.update(tvc, tvcA);											// 更新当前广告费用记录
			}
		}
	}
	
	// 活动总结操作
	private void opera(Long id, String areaId, String type, Double cost, Double negotiateCost) {
		TtVsCostPO tvc = new TtVsCostPO();
		tvc.setAreaId(Long.parseLong(areaId)) ;
		tvc.setCostType(Integer.parseInt(type)) ;
		
		if (Constant.COST_TYPE_01.toString().equals(type)) {
			tvc.setDealerId(id) ;
		} else {
			tvc.setOrgId(id);
		}
		
		TtVsCostPO tvcA = new TtVsCostPO();

		costUpdate(cost, negotiateCost, getCodeName(type), tvc, tvcA) ;
	}
	
	// 活动总结操作
	private void costUpdate(Double cost, Double negotiateCost, String typeName, TtVsCostPO tvc, TtVsCostPO tvcA) {
		Double freezeAmount = new Double(0);									// 冻结资金
		Double availableAmount = new Double(0);									// 可用余额
		Double costAmount = new Double(0);										// 帐户余额
		
		if (cost > 0) {
			List<TtVsCostPO> costList = dao.select(tvc);						

			if (!CommonUtils.isNullList(costList)) {
				// 审核通过
				freezeAmount = costList.get(0).getFreezeAmount() - cost;					// 释放冻结资金
				availableAmount = costList.get(0).getAvailableAmount() + cost - negotiateCost;		// 释放并修改可用余额
				costAmount = costList.get(0).getCostAmount() - negotiateCost;				// 修改帐户资金
				
				/*// 检验广告可用余额是否小于0.若小于0,则抛出异常
				if(availableAmount < 0) {
					throw new RuntimeException(typeName + "可用余额不足") ;
				}
				// 检验广告帐户是否小于0.若小于0,则抛出异常
				if(costAmount < 0) {
					throw new RuntimeException(typeName + "帐户金额不足") ;
				}*/

				tvcA.setFreezeAmount(freezeAmount);
				tvcA.setAvailableAmount(availableAmount);
				tvcA.setCostAmount(costAmount);

				dao.update(tvc, tvcA);											// 更新当前广告费用记录
			}
		}
	}
	
	// 根据费用类型id获取费用类型名称
	private String getCodeName(String type) {
		TcCodePO tc = new TcCodePO() ;
		tc.setCodeId(type) ;
		
		List<TcCodePO> tcList = dao.select(tc) ;
		
		if (!CommonUtils.isNullList(tcList)) {
			return tcList.get(0).getCodeDesc() ;
		} else {
			throw new RuntimeException("费用类型不存在！") ;
		}
	}
	
	@Override
	protected PO wrapperPO(ResultSet rs, int idx) {
		// TODO Auto-generated method stub
		return null;
	}
}
